<?php
declare(strict_types=1);
/**
 * Notes:
 * User: ysian
 * Time: 20:33
 * @return
 */

namespace Ysian\Storage\adapter;

use Ysian\Storage\exception\StorageException;

abstract class AdapterAbstract implements AdapterInterface
{
    # 基础默认配置
    protected int $nums            = 10; // 限制上传数量
    protected int $singleLimit     = 1024 * 1024 * 200;  //单个文件最大字节数
    protected int $totalLimit      = 1024 * 1024 * 200;  //总最大字节数
    protected array $files         = []; //文件储存对象
    protected array $includes      = []; //被允许的文件上传类型
    protected array $excludes      = []; //不被允许的文件上传类型
    protected array $config        = []; //当前储存配置
    protected string $hashType     = 'md5';      //命名规则 eg：md5：对文件使用md5_file散列生成，sha1：对文件使用sha1_file散列生成.
    protected string $dirname      = 'uploads';  //上传目录
    protected string $verify       = '';
    protected string $save         = '';
    protected array $imgExtentionArr  = ['jpg','png','jpeg','webp'];

    public function __construct(array $config = [])
    {
        $this->loadConfig($config);
        $this->files    =  PHP_SAPI=='cli' ? request()->file() : $_FILES;
        if(count($this->files)>$this->config['nums']){
            throw new StorageException('上传文件数量不能超过'.$this->config['nums'].'个');
        }
    }

    /**
     * @desc 加载配置文件
     * @param array $config
     */
    private function loadConfig(array $config = [])
    {
        $this->config                 = $config;
        $this->config['include']      = $config['include'] ?? $this->includes;
        $this->config['exclude']      = $config['exclude'] ?? $this->excludes;
        $this->config['single_limit'] = $config['single_limit'] ?? $this->singleLimit;
        $this->config['total_limit']  = $config['total_limit'] ?? $this->totalLimit;
        $this->config['nums']         = $config['nums'] ?? $this->nums; //限制数量
        $this->config['hashType']     = $config['hash_type'] ?? $this->hashType; //类型
        $this->config['dirname']      = $config['dirname'] ?? $this->dirname; //上传目录
        $this->config['verify']       = $config['verify'] ?? $this->verify; //上传目录
        $this->config['save']         = $config['save'] ?? $this->save; //是否保存
        if (is_callable($this->config['dirname'])) {
            $this->config['dirname'] = (string) $this->config['dirname']() ?: $this->config['dirname'];
        }
    }


    /**
     * 判断数据是否已储存
     * @param string $hash
     * @return string
     */
    public function getAttamentInfo(string $hash)
    {
        if (!is_callable($this->config['verify']))  return '';
        if (!$attachment  = $this->config['verify']($hash)) return '';
        $temp = [
            'origin_name' => $attachment['origin_name'],
            'name'        => $attachment['name'],
            'save_path'   => $attachment['save_path'],
            'url'         => $attachment['url'],
            'mime'        => $attachment['mime'],
            'extension'   => $attachment['extension'],
            'size'        => $attachment['size'],
            'hash'        => $attachment['hash'],
            'hash_type'   => $attachment['hash_type'],
            'driver'      => $attachment['driver'],
        ];
        if(!empty($attachment['width'])) {
            $temp['width']     = $attachment['width'];
            $temp['height']    = $attachment['height'];
        }
        return $temp;
    }

    /**
     * @desc 获取图片宽高
     * @param string $path
     * @return array
     */
    public function file(string $path)
    {
        $image_with = $image_height = 0;
        $mime_type  = '';
        if ($img_info = getimagesize($path)) {
            $mime_type = $img_info['mime'];
            [$image_with, $image_height] = $img_info;
        }
        return [$image_with,$image_height,$mime_type];
    }

    /**
     * @desc 保存附件
     * @param array $data
     */
    public function saveAttament(array $data)
    {
        try {
            if (is_callable($this->config['save']) && $data) $this->config['save']($data);
        } catch (StorageException $e){}
    }

    public function checkFile($extension)
    {
        if(!empty($this->config['include']) && !in_array($extension, $this->config['include'])){
            throw new StorageException('不允许'.$extension.'文件类型上传');
        }
        if(!empty($this->config['exclude']) && in_array($extension, $this->config['exclude'])){
            throw new StorageException('不允许'.$extension.'文件类型上传');
        }
    }

}